using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using MOSSExtractor;

namespace cmdPageLayoutExtractor
{
    class Program
    {
        public static void DumpException(Exception ex)
        {

            WriteExceptionInfo(ex);
            if (null != ex.InnerException)
            {
                WriteExceptionInfo(ex.InnerException);
            }

        }

        public static void WriteExceptionInfo(Exception ex)
        {

            Console.WriteLine("--------- Exception Data ---------");

            Console.WriteLine("Message: {0}", ex.Message);
            Console.WriteLine("Exception Type: {0}", ex.GetType().FullName);

            Console.WriteLine("Source: {0}", ex.Source);

            Console.WriteLine("StrackTrace: {0}", ex.StackTrace);

            Console.WriteLine("TargetSite: {0}", ex.TargetSite);
        }


        static void Main(string[] args)
        {
            try
            {

                if (args.Length < 8)
                {
                    Console.WriteLine("Usage {0} -url SiteCollectionURL -pagelayout PageLayout -directory OutputDirectory -featurenamespace FeatureNamespace -newpagelayout NewPageLayout ", Environment.CommandLine);
                    return;
                }
                Parameters parameters = new Parameters();
                if (!parameters.ReadParameters(args))
                {
                    Console.WriteLine("Error\r\nUsage {0} -url SiteCollectionURL -pagelayout PageLayout -directory OutputDirectory -featurenamespace FeatureNamespace -newpagelayout NewPageLayout ", Environment.CommandLine);
                    return;
                }

                
                string dirname = parameters.OutputDirectory;
                string featureNamespaceRoot = parameters.FeatureNamespaceRoot;
                string siteCollectionUrl = parameters.Url;
                string layoutName = parameters.PagelayoutName;
                string newLayoutName = layoutName;
                if (args.Length > 8)
                {
                    newLayoutName = parameters.NewPagelayoutName;
                }
                if (!Directory.Exists(dirname))
                    Directory.CreateDirectory(dirname);

                Directory.SetCurrentDirectory(dirname);
                Directory.CreateDirectory(featureNamespaceRoot + ".Page");

                using (SPSite site = new SPSite(siteCollectionUrl))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPList list = web.Lists["Master Page Gallery"];
                        foreach (SPListItem item in list.Items)
                        {
                            if (item.File.Name.Equals(layoutName))
                            {
                                SPFile file = item.File;
                                Solution solution = new Solution();
                                solution.SolutionId = Guid.NewGuid().ToString();
                                FeatureManifestReference featureref = new FeatureManifestReference();
                                featureref.Location = featureNamespaceRoot + ".Page\\feature.xml";
                                solution.FeatureManifests.Add(featureref);
                                solution.Serialize(dirname + "\\manifest.xml");


                                FeatureDefinition featPages = new FeatureDefinition();
                                featPages.Title = newLayoutName;
                                featPages.Id = Guid.NewGuid().ToString();
                                featPages.Scope = "Site";

                                ElementManifestDefinition contentTypeDefinition = new ElementManifestDefinition();

                                contentTypeDefinition.Location = "pages.xml";
                                featPages.ElementManifests.Add(contentTypeDefinition);
                                if (featPages.Validate())
                                    featPages.Serialize(dirname + "\\" + featureNamespaceRoot + ".Page\\feature.xml");
                                else
                                    Console.WriteLine(featPages.LastError);
                                string fName = dirname + "\\" + featureNamespaceRoot + ".Page\\" + newLayoutName;
                                File.WriteAllBytes(fName, item.File.OpenBinary());
                                Elements ContentTypeElements = new MOSSExtractor.Elements();
                                ModuleDefinition module = new ModuleDefinition();
                                module.Name = newLayoutName;
                                module.Url = file.Url.Substring(0, file.Url.Length - (file.Name.Length + 1));
                                module.RootWebOnly = "TRUE";
                                module.Path = "";
                                FileDefinition fdef = new FileDefinition();
                                fdef.Url = newLayoutName;
                                fdef.Type = "GhostableInLibrary";
                                System.Collections.Hashtable hash = file.Properties;
                                System.Collections.ICollection keys = hash.Keys;

                                PropertyValueAttributeDefinition property = new PropertyValueAttributeDefinition();
                                property.Name = "Title";
                                property.Value = item.Title;
                                fdef.Items.Add(property);

                                foreach (object key in keys)
                                {
                                    if (!key.ToString().StartsWith("vti_"))
                                    {
                                        property = new PropertyValueAttributeDefinition();
                                        property.Name = key.ToString();
                                        property.Value = hash[key.ToString()].ToString();
                                        fdef.Items.Add(property);
                                    }
                                }



                                module.Files.Add(fdef);


                                ContentTypeElements.Modules.Add(module);
                                ContentTypeElements.Serialize(dirname + "\\" + featureNamespaceRoot + ".Page\\pages.xml");
                                StreamWriter swddf = new StreamWriter(dirname + "\\package.ddf");
                                swddf.WriteLine(".OPTION Explicit ; Generate errors");
                                swddf.WriteLine(".Set CabinetNameTemplate=\"" + file.Title + "\".wsp");
                                swddf.WriteLine(".Set DiskDirectoryTemplate=CDROM");
                                swddf.WriteLine(".Set CompressionType=MSZIP");
                                swddf.WriteLine(".Set UniqueFiles=Off");
                                swddf.WriteLine(".Set Cabinet=On");
                                swddf.WriteLine(".Set DiskDirectory1=Package");
                                swddf.WriteLine(";");
                                swddf.WriteLine("; \\");
                                swddf.WriteLine(";**************************************************");
                                swddf.WriteLine("manifest.xml");
                                swddf.WriteLine(".Set DestinationDir=\"" + featureNamespaceRoot + ".Page\"");
                                swddf.WriteLine("\"" + featureNamespaceRoot + ".Page\\Feature.xml\"");
                                swddf.WriteLine("\"" + featureNamespaceRoot + ".Page\\pages.xml\"");
                                swddf.WriteLine("\"" + fName + "\"");
                                swddf.Flush();
                                swddf.Close();
                                try
                                {
                                    System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(@"makecab.exe");
                                    psi.WorkingDirectory = dirname;
                                    psi.Arguments = "/f package.ddf";
                                    psi.RedirectStandardOutput = true;
                                    psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                                    psi.UseShellExecute = false;
                                    System.Diagnostics.Process listFiles;
                                    listFiles = System.Diagnostics.Process.Start(psi);
                                    System.IO.StreamReader myOutput = listFiles.StandardOutput;
                                    listFiles.WaitForExit(2000);
                                    if (listFiles.HasExited)
                                    {
                                        string output = myOutput.ReadToEnd();
                                        Console.WriteLine(output);
                                    }
                                }
                                catch (Exception CabEx)
                                {
                                    Console.WriteLine("Couldn't invoke the makecab exe, please download the cabinet sdk and run the makecab.exe program from {0} directory using the parameters /f package.ddf", dirname);
                                }

                                StreamWriter sw = new StreamWriter(dirname + "\\InstallSolution.bat");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o addsolution -filename \"" + dirname + "\\Package\\" + file.Title + ".wsp\"");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o deploysolution -name \"" + file.Title + ".wsp\" -local");
                                sw.Flush();
                                sw.Close();
                                sw = new StreamWriter(dirname + "\\ActivateFeatures.bat");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o activatefeature -filename " + featureNamespaceRoot + ".page\\feature.xml -url %1");
                                sw.Flush();
                                sw.Close();
                                sw = new StreamWriter(dirname + "\\DeActivateFeatures.bat");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o deactivatefeature -filename " + featureNamespaceRoot + ".page\\feature.xml -url %1");
                                sw.Flush();
                                sw.Close();
                                sw = new StreamWriter(dirname + "\\UnInstallSolution.bat");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o retractsolution -name \"" + file.Name + ".wsp\" -local");
                                sw.WriteLine("\"c:\\program files\\common files\\microsoft shared\\web server extensions\\12\\bin\\stsadm.exe\" -o deletesolution -name \"" + file.Name + ".wsp\"");
                                sw.Flush();
                                sw.Close();


                                break;

                            }
                        }

                    }

                }
            }
            catch (Exception Ex)
            {
                DumpException(Ex);
            }
        }
    }
}
